<template>
  <div
    class="td-button"
    :class="className"
    tabindex="0"
    @click="click"
    @mousedown="mousedown"
    @mouseup="mouseup"
  >
    <ElIcon v-if="loading" class="is-loading">
      <Loading />
    </ElIcon>

    <Icon v-if="iconName !== ''" :name="iconName" :prefix="iconPrefix" class="icon" color="#fff" />

    <span v-if="text" class="button-text" :class="{ text: iconName !== '' }">
      {{ text }}
    </span>
    <slot></slot>
  </div>
</template>

<script lang="ts"></script>

<script lang="ts" setup>
  import { computed, unref } from 'vue';

  defineOptions({
    name: 'CsButton',
  });

  const props = defineProps({
    // 类型 normal/guide/warn/radio/disabled/link/icon
    type: {
      type: String,
      default: 'normal',
    },
    // 文字
    text: {
      type: String,
      default: '',
    },
    // 图标名
    iconName: {
      type: String,
      default: '',
    },
    // 图标前索引
    iconPrefix: {
      type: String,
      default: '',
    },
    // 尺寸	default/auto/mini/small/big
    size: {
      type: String,
      default: '',
    },
    iconDirection: {
      type: String,
      default: '',
    },
    // 禁用
    disable: {
      type: Boolean,
      default: false,
    },
    // 加载中
    loading: {
      type: Boolean,
      default: false,
    },
    // 默认是否聚焦
    active: {
      type: Boolean,
      default: false,
    },
    radius: Boolean,
    border: Boolean,
  });
  const emit = defineEmits(['click', 'mousedown', 'mouseup']);

  const isDisabled = computed(() => {
    return props.disable || props.loading;
  });
  const className = computed(() => {
    const { type, iconDirection, size, active, radius, border } = props;
    const cls = {
      normal: type === 'normal',
      guide: type === 'guide',
      warn: type === 'warn',
      radio: type === 'radio',
      link: type === 'link',
      icon: type === 'icon',
      disabled: unref(isDisabled),
      radius: radius,
      'size-auto': size === 'auto',
      'border-normal': border && type === 'normal',
      'border-guide': border && type === 'guide',
      'border-warn': border && type === 'warn',
      'radio-special': type === 'radioSpecial',
      'radio-warn': type === 'radioWarn',
      'radio-success': type === 'radioSuccess',
      'icon-opacity': type === 'iconOpacity',
      'icon-normal': type === 'iconNormal',
      'icon-special': type === 'iconSpecial',
      'icon-right': iconDirection === 'iconRight',
      'icon-bottom': iconDirection === 'iconBottom',
    };

    Object.keys(cls).forEach((key) => {
      if (!cls[key]) return;
      if (size) {
        cls[key + '_' + size] = true;
      }
      if (active) {
        cls[key + '_active'] = true;
      }
    });

    return cls;
  });
  const borderPaste = computed(() => {
    if (props.size === 'big') {
      return '3px';
    }
    return '2px';
  });

  function click(e) {
    if (isDisabled.value) return;
    emit('click', e);
  }

  function mousedown(e) {
    emit('mousedown', e);
  }

  function mouseup(e) {
    emit('mouseup', e);
  }
</script>

<style lang="less" scoped>
  .td-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100px;
    height: 32px;
    padding: 2px 6px;
    background: var(--button-color-normal-default);
    cursor: pointer;

    &:hover {
      background: var(--button-color-normal-hover);

      .icon {
        fill: var(--icon-color-normal);
      }
    }

    &_active {
      background: var(--button-color-normal-click);
    }

    .icon {
      width: 14px;
      height: 14px;
      fill: var(--icon-color-normal);

      ::before {
        content: '';
        display: block;
        padding-bottom: 100%;
      }
    }

    .text {
      margin-left: 3px;
    }

    .button-text {
      font-size: 14px;
    }
  }

  .normal {
    position: relative;
    border: 1px solid rgb(77 147 201 / 60%);
    background: linear-gradient(
      90deg,
      rgb(31 115 159 / 16%) 0%,
      rgb(21 154 255 / 16%) 0%,
      rgb(153 206 251 / 16%) 100%
    );

    &::before {
      content: '';
      position: absolute;
      left: 0;
      width: v-bind(borderpaste);
      height: 60%;
      transform: perspective(0.1em) rotateY(10deg);
      background: rgb(78 122 159 / 100%);
    }

    &::after {
      content: '';
      position: absolute;
      right: 0;
      width: v-bind(borderpaste);
      height: 60%;
      transform: perspective(0.1em) rotateY(-10deg);
      background: rgb(78 122 159 / 100%);
    }

    &:hover,
    &_active {
      border: 1px solid rgb(26 255 251 / 100%);
      background: linear-gradient(180deg, rgb(0 115 168 / 67%) 0%, rgb(105 255 215 / 67%) 100%);
      box-shadow: inset 0 0 4px rgb(26 255 251 / 100%);

      &::before {
        content: '';
        position: absolute;
        left: 0;
        width: v-bind(borderpaste);
        height: 60%;
        transform: perspective(0.1em) rotateY(10deg);
        background: rgb(26 255 251 / 100%);
      }

      &::after {
        content: '';
        position: absolute;
        right: 0;
        width: v-bind(borderpaste);
        height: 60%;
        transform: perspective(0.1em) rotateY(-10deg);
        background: rgb(26 255 251 / 100%);
      }
    }
  }

  .guide {
    background: url('@/assets/images/button/normal_bg.png') no-repeat;
    background-size: 100% 100%;

    &:hover,
    &_active {
      background: url('@/assets/images/button/normal_bg_active.png') no-repeat;
      background-size: 100% 100%;
    }
  }

  .warn {
    background: var(--button-color-warn-default);

    &_active {
      background: var(--button-color-warn-click);
    }

    &:hover {
      background: var(--button-color-warn-hover);
    }
  }

  .disabled {
    cursor: not-allowed;
  }

  .link {
    background: none;
    color: var(--button-link);

    &:hover {
      background: none;

      .icon {
        fill: var(--icon-color-hover);
      }
    }

    &_active {
      background: none;
    }
  }

  .size-auto {
    width: auto;
    height: auto;
  }

  .radius {
    border-radius: 4px;
  }

  .border-normal {
    border: 1px solid var(--button-color-normal-hover);
  }

  .border-guide {
    border: 1px solid var(--button-color-guide-hover);
  }

  .border-warn {
    border: 1px solid var(--button-color-warn-hover);
  }

  .icon {
    background: none;
    color: var(--icon-color-normal);

    &:hover {
      background: none;
    }

    &_active {
      background: none;
    }
  }

  .icon-opacity {
    width: 40px;
    height: 40px;
    border: 0;
    border-radius: 50%;
    background: rgb(105 105 105 / 20%) !important;

    &:hover {
      background: rgb(105 105 105 / 80%) !important;
    }
  }

  .icon-normal {
    width: 40px;
    height: 40px;
    border: 0;
    background: transparent !important;

    &:hover {
      background: var(--button-color-normal-hover);
    }

    &_active {
      background: transparent !important;
    }
  }

  .icon-special {
    width: 40px;
    height: 40px;
    border: 0;
    background: transparent !important;

    &:hover {
      background: var(--button-color-warn-hover) !important;
      fill: var(--text-color-button) !important;
    }
  }

  .icon-right {
    flex-direction: row-reverse !important;
  }

  .icon-bottom {
    flex-direction: row-reverse;
  }

  .radio {
    width: 40px;
    height: 40px;
    border: 1px solid var(--border-color-default);
    border-radius: 50%;
    background: var(--button-color-radio);

    .icon {
      width: 20px;
      height: 20px;
      fill: var(--icon-color-default);
    }
  }

  .radio-special {
    width: 40px;
    height: 40px;
    border: 1px solid rgb(77 147 201 / 60%);
    border-radius: 50%;
    background: var(--button-color-radio);

    .icon {
      width: 25px;
      height: 25px;
      fill: var(--icon-color-default);
    }

    &:hover {
      background: var(--button-color-special-active);
    }

    &_active {
      border: none;
      background: var(--button-color-special-active);

      .icon {
        fill: var(--icon-color-normal) !important;
      }
    }

    &_small {
      width: 20px;
      height: 20px;

      .icon {
        width: 10px;
        height: 10px;
      }
    }
  }

  .radio-warn {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--button-color-warn-default);

    &:hover {
      background: var(--button-color-warn-hover);
    }

    .icon {
      width: 20px;
      height: 20px;
      fill: var(--icon-color-normal);
    }

    &_small {
      width: 20px;
      height: 20px;

      .icon {
        width: 10px;
        height: 10px;
      }
    }
  }

  .radio-success {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--button-color-success);

    &:hover {
      background: var(--button-color-success-hover);
    }

    .icon {
      width: 20px;
      height: 20px;
      fill: var(--icon-color-normal);
    }
  }
</style>
